home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Python / modsupport.c < prev    next >
Text File  |  1996-01-26  |  10KB  |  473 lines

  1. /***********************************************************
  2. Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
  3. The Netherlands.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Stichting Mathematisch
  12. Centrum or CWI not be used in advertising or publicity pertaining to
  13. distribution of the software without specific, written prior permission.
  14.  
  15. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  16. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17. FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  18. FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  20. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  21. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  
  23. ******************************************************************/
  24.  
  25. /* Module support implementation */
  26.  
  27. #include "allobjects.h"
  28. #include "import.h"
  29.  
  30. #ifdef MPW /* MPW pushes 'extended' for float and double types with varargs */
  31. typedef extended va_double;
  32. #else
  33. typedef double va_double;
  34. #endif
  35.  
  36. /* initmodule4() parameters:
  37.    - name is the module name
  38.    - methods is the list of top-level functions
  39.    - doc is the documentation string
  40.    - passthrough is passed as self to functions defined in the module
  41.    - api_version is the value of PYTHON_API_VERSION at the time the
  42.      module was compiled
  43. */
  44.  
  45. static char api_version_warning[] =
  46. "WARNING: Python C API version mismatch for module %s:\n\
  47.   This Python has API version %d, module %s has version %d.\n";
  48.  
  49. object *
  50. initmodule4(name, methods, doc, passthrough, module_api_version)
  51.     char *name;
  52.     struct methodlist *methods;
  53.     char *doc;
  54.     object *passthrough;
  55.     int module_api_version;
  56. {
  57.     object *m, *d, *v;
  58.     struct methodlist *ml;
  59.     if (module_api_version != PYTHON_API_VERSION)
  60.         fprintf(stderr, api_version_warning,
  61.             name, PYTHON_API_VERSION, name, module_api_version);
  62.     if ((m = add_module(name)) == NULL) {
  63.         fprintf(stderr, "initializing module: %s\n", name);
  64.         fatal("can't create a module");
  65.     }
  66.     d = getmoduledict(m);
  67.     for (ml = methods; ml->ml_name != NULL; ml++) {
  68.         v = newmethodobject(ml, passthrough);
  69.         if (v == NULL || dictinsert(d, ml->ml_name, v) != 0) {
  70.             fprintf(stderr, "initializing module: %s\n", name);
  71.             fatal("can't initialize module");
  72.         }
  73.         DECREF(v);
  74.     }
  75.     if (doc != NULL) {
  76.         v = newstringobject(doc);
  77.         if (v == NULL || dictinsert(d, "__doc__", v) != 0)
  78.             fatal("can't add doc string");
  79.         DECREF(v);
  80.     }
  81.     return m;
  82. }
  83.  
  84.  
  85. /* Helper for mkvalue() to scan the length of a format */
  86.  
  87. static int countformat PROTO((char *format, int endchar));
  88. static int countformat(format, endchar)
  89.     char *format;
  90.     int endchar;
  91. {
  92.     int count = 0;
  93.     int level = 0;
  94.     while (level > 0 || *format != endchar) {
  95.         switch (*format) {
  96.         case '\0':
  97.             /* Premature end */
  98.             err_setstr(SystemError, "unmatched paren in format");
  99.             return -1;
  100.         case '(':
  101.         case '[':
  102.         case '{':
  103.             if (level == 0)
  104.                 count++;
  105.             level++;
  106.             break;
  107.         case ')':
  108.         case ']':
  109.         case '}':
  110.             level--;
  111.             break;
  112.         case '#':
  113.         case '&':
  114.         case ',':
  115.         case ':':
  116.         case ' ':
  117.         case '\t':
  118.             break;
  119.         default:
  120.             if (level == 0)
  121.                 count++;
  122.         }
  123.         format++;
  124.     }
  125.     return count;
  126. }
  127.  
  128.  
  129. /* Generic function to create a value -- the inverse of getargs() */
  130. /* After an original idea and first implementation by Steven Miale */
  131.  
  132. static object *do_mktuple PROTO((char**, va_list *, int, int));
  133. static object *do_mklist PROTO((char**, va_list *, int, int));
  134. static object *do_mkdict PROTO((char**, va_list *, int, int));
  135. static object *do_mkvalue PROTO((char**, va_list *));
  136.  
  137.  
  138. static object *
  139. do_mkdict(p_format, p_va, endchar, n)
  140.     char **p_format;
  141.     va_list *p_va;
  142.     int endchar;
  143.     int n;
  144. {
  145.     object *d;
  146.     int i;
  147.     if (n < 0)
  148.         return NULL;
  149.     if ((d = newdictobject()) == NULL)
  150.         return NULL;
  151.     for (i = 0; i < n; i+= 2) {
  152.         object *k, *v;
  153.         k = do_mkvalue(p_format, p_va);
  154.         if (k == NULL) {
  155.             DECREF(d);
  156.             return NULL;
  157.         }
  158.         v = do_mkvalue(p_format, p_va);
  159.         if (v == NULL) {
  160.             DECREF(k);
  161.             DECREF(d);
  162.             return NULL;
  163.         }
  164.         if (dict2insert(d, k, v) < 0) {
  165.             DECREF(k);
  166.             DECREF(v);
  167.             DECREF(d);
  168.             return NULL;
  169.         }
  170.     }
  171.     if (d != NULL && **p_format != endchar) {
  172.         DECREF(d);
  173.         d = NULL;
  174.         err_setstr(SystemError, "Unmatched paren in format");
  175.     }
  176.     else if (endchar)
  177.         ++*p_format;
  178.     return d;
  179. }
  180.  
  181. static object *
  182. do_mklist(p_format, p_va, endchar, n)
  183.     char **p_format;
  184.     va_list *p_va;
  185.     int endchar;
  186.     int n;
  187. {
  188.     object *v;
  189.     int i;
  190.     if (n < 0)
  191.         return NULL;
  192.     if ((v = newlistobject(n)) == NULL)
  193.         return NULL;
  194.     for (i = 0; i < n; i++) {
  195.         object *w = do_mkvalue(p_format, p_va);
  196.         if (w == NULL) {
  197.             DECREF(v);
  198.             return NULL;
  199.         }
  200.         setlistitem(v, i, w);
  201.     }
  202.     if (v != NULL && **p_format != endchar) {
  203.         DECREF(v);
  204.         v = NULL;
  205.         err_setstr(SystemError, "Unmatched paren in format");
  206.     }
  207.     else if (endchar)
  208.         ++*p_format;
  209.     return v;
  210. }
  211.  
  212. static object *
  213. do_mktuple(p_format, p_va, endchar, n)
  214.     char **p_format;
  215.     va_list *p_va;
  216.     int endchar;
  217.     int n;
  218. {
  219.     object *v;
  220.     int i;
  221.     if (n < 0)
  222.         return NULL;
  223.     if ((v = newtupleobject(n)) == NULL)
  224.         return NULL;
  225.     for (i = 0; i < n; i++) {
  226.         object *w = do_mkvalue(p_format, p_va);
  227.         if (w == NULL) {
  228.             DECREF(v);
  229.             return NULL;
  230.         }
  231.         settupleitem(v, i, w);
  232.     }
  233.     if (v != NULL && **p_format != endchar) {
  234.         DECREF(v);
  235.         v = NULL;
  236.         err_setstr(SystemError, "Unmatched paren in format");
  237.     }
  238.     else if (endchar)
  239.         ++*p_format;
  240.     return v;
  241. }
  242.  
  243. static object *
  244. do_mkvalue(p_format, p_va)
  245.     char **p_format;
  246.     va_list *p_va;
  247. {
  248.     for (;;) {
  249.         switch (*(*p_format)++) {
  250.         case '(':
  251.             return do_mktuple(p_format, p_va, ')',
  252.                       countformat(*p_format, ')'));
  253.  
  254.         case '[':
  255.             return do_mklist(p_format, p_va, ']',
  256.                      countformat(*p_format, ']'));
  257.  
  258.         case '{':
  259.             return do_mkdict(p_format, p_va, '}',
  260.                      countformat(*p_format, '}'));
  261.  
  262.         case 'b':
  263.         case 'h':
  264.         case 'i':
  265.             return newintobject((long)va_arg(*p_va, int));
  266.  
  267.         case 'l':
  268.             return newintobject((long)va_arg(*p_va, long));
  269.  
  270.         case 'f':
  271.         case 'd':
  272.             return newfloatobject((double)va_arg(*p_va, va_double));
  273.  
  274.         case 'c':
  275.         {
  276.             char p[1];
  277.             p[0] = va_arg(*p_va, int);
  278.             return newsizedstringobject(p, 1);
  279.         }
  280.  
  281.         case 's':
  282.         case 'z':
  283.         {
  284.             object *v;
  285.             char *str = va_arg(*p_va, char *);
  286.             int n;
  287.             if (**p_format == '#') {
  288.                 ++*p_format;
  289.                 n = va_arg(*p_va, int);
  290.             }
  291.             else
  292.                 n = -1;
  293.             if (str == NULL) {
  294.                 v = None;
  295.                 INCREF(v);
  296.             }
  297.             else {
  298.                 if (n < 0)
  299.                     n = strlen(str);
  300.                 v = newsizedstringobject(str, n);
  301.             }
  302.             return v;
  303.         }
  304.  
  305.         case 'S':
  306.         case 'O':
  307.         if (**p_format == '&') {
  308.             typedef object *(*converter) PROTO((void *));
  309.             converter func = va_arg(*p_va, converter);
  310.             void *arg = va_arg(*p_va, void *);
  311.             ++*p_format;
  312.             return (*func)(arg);
  313.         }
  314.         else {
  315.             object *v;
  316.             v = va_arg(*p_va, object *);
  317.             if (v != NULL)
  318.                 INCREF(v);
  319.             else if (!err_occurred())
  320.                 /* If a NULL was passed
  321.                  * because a call that should
  322.                  * have constructed a value
  323.                  * failed, that's OK, and we
  324.                  * pass the error on; but if
  325.                  * no error occurred it's not
  326.                  * clear that the caller knew
  327.                  * what she was doing. */
  328.                 err_setstr(SystemError,
  329.                        "NULL object passed to mkvalue");
  330.             return v;
  331.         }
  332.  
  333.         case ':':
  334.         case ',':
  335.         case ' ':
  336.         case '\t':
  337.             break;
  338.  
  339.         default:
  340.             err_setstr(SystemError,
  341.                    "bad format char passed to mkvalue");
  342.             return NULL;
  343.  
  344.         }
  345.     }
  346. }
  347.  
  348.  
  349. #ifdef HAVE_STDARG_PROTOTYPES
  350. /* VARARGS 2 */
  351. object *mkvalue(char *format, ...)
  352. #else
  353. /* VARARGS */
  354. object *mkvalue(va_alist) va_dcl
  355. #endif
  356. {
  357.     va_list va;
  358.     object* retval;
  359. #ifdef HAVE_STDARG_PROTOTYPES
  360.     va_start(va, format);
  361. #else
  362.     char *format;
  363.     va_start(va);
  364.     format = va_arg(va, char *);
  365. #endif
  366.     retval = vmkvalue(format, va);
  367.     va_end(va);
  368.     return retval;
  369. }
  370.  
  371. object *
  372. vmkvalue(format, va)
  373.     char *format;
  374.     va_list va;
  375. {
  376.     char *f = format;
  377.     int n = countformat(f, '\0');
  378.     va_list lva;
  379.  
  380. #ifdef VA_LIST_IS_ARRAY
  381.     memcpy(lva, va, sizeof(va_list));
  382. #else
  383.     lva = va;
  384. #endif
  385.  
  386.     if (n < 0)
  387.         return NULL;
  388.     if (n == 0) {
  389.         INCREF(None);
  390.         return None;
  391.     }
  392.     if (n == 1)
  393.         return do_mkvalue(&f, &lva);
  394.     return do_mktuple(&f, &lva, '\0', n);
  395. }
  396.  
  397.  
  398. #ifdef HAVE_STDARG_PROTOTYPES
  399. object *
  400. PyEval_CallFunction(object *obj, char *format, ...)
  401. #else
  402. object *
  403. PyEval_CallFunction(obj, format, va_alist)
  404.     object *obj;
  405.     char *format;
  406.     va_dcl
  407. #endif
  408. {
  409.     va_list vargs;
  410.     object *args;
  411.     object *res;
  412.  
  413. #ifdef HAVE_STDARG_PROTOTYPES
  414.     va_start(vargs, format);
  415. #else
  416.     va_start(vargs);
  417. #endif
  418.  
  419.     args = vmkvalue(format, vargs);
  420.     va_end(vargs);
  421.  
  422.     if (args == NULL)
  423.         return NULL;
  424.  
  425.     res = call_object(obj, args);
  426.     DECREF(args);
  427.  
  428.     return res;
  429. }
  430.  
  431.  
  432. #ifdef HAVE_STDARG_PROTOTYPES
  433. object *
  434. PyEval_CallMethod(object *obj, char *methonname, char *format, ...)
  435. #else
  436. object *
  437. PyEval_CallMethod(obj, methonname, format, va_alist)
  438.     object *obj;
  439.     char *methonname;
  440.     char *format;
  441.     va_dcl
  442. #endif
  443. {
  444.     va_list vargs;
  445.     object *meth;
  446.     object *args;
  447.     object *res;
  448.  
  449.     meth = getattr(obj, methonname);
  450.     if (meth == NULL)
  451.         return NULL;
  452.  
  453. #ifdef HAVE_STDARG_PROTOTYPES
  454.     va_start(vargs, format);
  455. #else
  456.     va_start(vargs);
  457. #endif
  458.  
  459.     args = vmkvalue(format, vargs);
  460.     va_end(vargs);
  461.  
  462.     if (args == NULL) {
  463.         DECREF(meth);
  464.         return NULL;
  465.     }
  466.  
  467.     res = call_object(meth, args);
  468.     DECREF(meth);
  469.     DECREF(args);
  470.  
  471.     return res;
  472. }
  473.